package com.yanqu.road.server.manager.unionwar;

import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.unionwar.UnionQunyingTimeInfo;
import com.yanqu.road.entity.activity.unionwar.cross.CrossUnionWarSimple;
import com.yanqu.road.entity.activity.unionwar.cross.CrossUnionWarState;
import com.yanqu.road.entity.enums.eUnionWarRankConditionType;
import com.yanqu.road.entity.rank.UnionActivityRank;
import com.yanqu.road.entity.union.activitygroup.UnionActivityGroup;
import com.yanqu.road.entity.unionwar.UnionWarChampionUnionInfo;
import com.yanqu.road.logic.bussiness.activity.UnionWarActivityBusiness;
import com.yanqu.road.logic.bussiness.rank.RankBussiness;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.logic.cross.CrossUnionWarRankListModel;
import com.yanqu.road.logic.helper.ActivityHelper;
import com.yanqu.road.logic.helper.UnionActivityGroupHelper;
import com.yanqu.road.logic.pb.UnionBasePb;
import com.yanqu.road.pb.activity.unionwar.CrossUnionWarProto;
import com.yanqu.road.server.CrossBaseServer;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.logic.MessageHelper;
import com.yanqu.road.server.manager.union.activitygroup.Cross2UnionActivityGroupMgr;
import com.yanqu.road.server.protocol.GameProtocol;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class CrossUnionWarRankMgr extends TempMgr {

    public static Map<Integer, Map<Integer, Map<Integer, CrossUnionWarRankListModel>>> unionWarRankListModelMap;
    private static Map<Integer, Map<Integer, List<UnionWarChampionUnionInfo>>> unionWarChampionMap;
    private static Map<Integer, Map<Integer, List<String>>> initUnionRankOverMap;

    @Override
    public boolean reloadData() {
        unionWarRankListModelMap = new ConcurrentHashMap<>();
        unionWarChampionMap = UnionWarActivityBusiness.getUnionWarChampionMap();
        initUnionRankOverMap = new ConcurrentHashMap<>();
        initCrossRankListModelMap();
        return true;
    }

    public static Map<Integer, Map<Integer, Map<Integer, CrossUnionWarRankListModel>>> getUnionWarRankListModelMap() {
        return unionWarRankListModelMap;
    }

    private void initCrossRankListModelMap() {
        Map<Integer, ActivityInfo> activityInfoMap = CrossUnionWarActivityMgr.getOpenActivityMap();
        List<Integer> activityIdList = new ArrayList<>();
        for (ActivityInfo activityInfo : activityInfoMap.values()) {
            activityIdList.add(activityInfo.getActivityId());
        }
        Map<Integer, Map<Integer, Map<Integer, LinkedList<UnionActivityRank>>>> crossUnionRankListMap = RankBussiness.getCrossUnionWarRankListMap(activityIdList);
        for (Map.Entry<Integer, Map<Integer, Map<Integer, LinkedList<UnionActivityRank>>>> entry : crossUnionRankListMap.entrySet()) {
            int activityId = entry.getKey();
            List<Integer> groupIdList = CrossUnionWarMgr.getGroupListByCrossServerId(activityId, (int)CrossBaseServer.getInstance().getServerId());
            for (Map.Entry<Integer, Map<Integer, LinkedList<UnionActivityRank>>> phaseEntry : entry.getValue().entrySet()) {
                for (Map.Entry<Integer, LinkedList<UnionActivityRank>> listEntry : phaseEntry.getValue().entrySet()) {
                    int groupId = listEntry.getKey();
                    if(!groupIdList.contains(groupId)){
                        continue;
                    }
                    CrossUnionWarRankListModel rankListModel = new CrossUnionWarRankListModel(entry.getKey(), phaseEntry.getKey(), groupId);
                    int conditionType = getConditionTypeByPhase(phaseEntry.getKey());
                    int maxRank = ActivityHelper.getMaxRankByConditionType(conditionType, CrossUnionWarActivityMgr.getActivityConditionInfoList(entry.getKey()));
                    if (maxRank <= 0) {
                        maxRank = GameConfig.RANK_DEFAULT_MAX_COUNT;
                    }
                    rankListModel.setRankNum(maxRank);
                    initCrossRankListModel(entry.getKey(), phaseEntry.getKey(), listEntry.getValue(), rankListModel, false);

                }
            }
        }
    }

    public static void initCrossRankListModel(int activityId, int phase, LinkedList<UnionActivityRank> rankList, CrossUnionWarRankListModel rankListModel, boolean isInit) {
        synchronized (unionWarRankListModelMap) {
            if (isInit) {
                if(phase == 2){
                    //是否到初始时间
                    int allSession = CrossUnionWarActivityMgr.getAllSession(activityId, 1);
                    CrossUnionWarState state = CrossUnionWarMgr.getCrossUnionWarState(activityId, 1, allSession, rankListModel.getGroupId());
                    if(state == null || state.getState() != 2){
                        getLogger().info("union war activity {} group {} not in phase 2, 榜单不能初始化", activityId, rankListModel.getGroupId());
                        return;
                    }
                }
                UnionQunyingTimeInfo qunyingTimeInfo = CrossUnionWarActivityMgr.getUnionQunyingTimeInfo(activityId, 2, 0);
                int finalsNum = 32;
                try{
                    finalsNum = Integer.valueOf(qunyingTimeInfo.getParam());
                }catch (Exception e){
                    getLogger().error(e.getMessage(), e);
                }
                int i = 1;
                LinkedList<UnionActivityRank> rankList1 =  new LinkedList<>();
                for (UnionActivityRank rank : rankList) {
                    if(phase == 2 && i > finalsNum){
                        break;
                    }
                    UnionActivityRank unionActivityRank = new UnionActivityRank(activityId, rankListModel.getGroupId());
                    unionActivityRank.setPhase(phase);
                    unionActivityRank.setUnionUid(rank.getUnionUid());
                    unionActivityRank.setUnionBaseInfo(rank.getUnionBaseInfo());
                    unionActivityRank.setLastUpdateTime(System.currentTimeMillis());
                    unionActivityRank.setValue(BigInteger.ZERO);
                    rankList1.add(unionActivityRank);
                    i++;
                }
                rankListModel.setRankList(rankList1);
            } else {
                rankListModel.setRankList(rankList);
            }

            if (!unionWarRankListModelMap.containsKey(activityId)) {
                unionWarRankListModelMap.put(activityId, new ConcurrentHashMap<>());
            }
            if (!unionWarRankListModelMap.get(activityId).containsKey(phase)){
                unionWarRankListModelMap.get(activityId).put(phase, new ConcurrentHashMap<>());
            }
            unionWarRankListModelMap.get(activityId).get(phase).put(rankListModel.getGroupId(), rankListModel);
        }
    }

    public static CrossUnionWarRankListModel getCrossUnionWarRankListModel(int activityId, int phase, int groupId) {
        if(phase <= 0){
            return null;
        }
        if(groupId == UnionActivityGroupHelper.NO_GROUP_ID){
            return null;
        }
        if (unionWarRankListModelMap.containsKey(activityId)) {
            if (!unionWarRankListModelMap.get(activityId).containsKey(phase)) {
                unionWarRankListModelMap.get(activityId).put(phase, new ConcurrentHashMap<>());
            }
            if (!unionWarRankListModelMap.get(activityId).get(phase).containsKey(groupId)){
                //将上一阶段排行同步到下一阶段
                CrossUnionWarRankListModel crossUnionWarRankListModel = getCrossUnionWarRankListModel(activityId, phase - 1, groupId);
                if (crossUnionWarRankListModel != null) {
                    CrossUnionWarRankListModel rankListModel = new CrossUnionWarRankListModel(activityId, phase, groupId);
                    int conditionType = getConditionTypeByPhase(phase);
                    int maxRank = ActivityHelper.getMaxRankByConditionType(conditionType, CrossUnionWarActivityMgr.getActivityConditionInfoList(activityId));
                    if (maxRank <= 0) {
                        maxRank = GameConfig.RANK_DEFAULT_MAX_COUNT;
                    }
                    rankListModel.setRankNum(maxRank);
                    initCrossRankListModel(activityId, phase, crossUnionWarRankListModel.getRankList(), rankListModel, true);
                }
            }
            return unionWarRankListModelMap.get(activityId).get(phase).get(groupId);
        }
        return null;
    }

    public static void changeUnionWarRank(int activityId, int phase, UnionActivityRank unionRank, boolean isInit, int groupId) {
        CrossUnionWarRankListModel rankListModel = getCrossUnionWarRankListModel(activityId, phase, groupId);
        if (rankListModel == null) {
            synchronized (unionWarRankListModelMap) {
                if (!unionWarRankListModelMap.containsKey(activityId)) {
                    unionWarRankListModelMap.put(activityId, new ConcurrentHashMap<>());
                }
                if (!unionWarRankListModelMap.get(activityId).containsKey(phase)) {
                    unionWarRankListModelMap.get(activityId).put(phase, new ConcurrentHashMap<>());
                }
                if (!unionWarRankListModelMap.get(activityId).get(phase).containsKey(groupId)) {
                    ActivityInfo activityInfo = CrossUnionWarActivityMgr.getOpenActivity(activityId);
                    if (activityInfo != null) {
                        CrossUnionWarRankListModel crossUnionWarRankListModel = new CrossUnionWarRankListModel(activityInfo.getActivityId(), phase, groupId);
                        int conditionType = getConditionTypeByPhase(phase);
                        int maxRank = ActivityHelper.getMaxRankByConditionType(conditionType, CrossUnionWarActivityMgr.getActivityConditionInfoList(activityInfo.getActivityId()));
                        if (maxRank <= 0) {
                            maxRank = GameConfig.RANK_DEFAULT_MAX_COUNT;
                        }
                        crossUnionWarRankListModel.setRankNum(maxRank);
                        unionWarRankListModelMap.get(activityId).get(phase).put(groupId, crossUnionWarRankListModel);
                    }
                }
            }
            rankListModel = getCrossUnionWarRankListModel(activityId, phase, groupId);
        }
        if (null != rankListModel) {
            rankListModel.rankChange(unionRank, isInit);
        }
    }

    public static void initUnionWarRankList(int activityId, int phase, int groupId) {
        synchronized (initUnionRankOverMap) {
            if (!initUnionRankOverMap.containsKey(activityId)) {
                initUnionRankOverMap.put(activityId, new ConcurrentHashMap<>());
            }
            if (!initUnionRankOverMap.get(activityId).containsKey(phase)) {
                initUnionRankOverMap.get(activityId).put(phase, new ArrayList<>());
            }
            List<CrossUnionWarSimple> crossUnionWarSimpleList = CrossUnionWarMgr.getCrossUnionWarSimpleList(activityId);
            crossUnionWarSimpleList = CrossUnionWarMgr.filterUnionData(activityId, groupId, crossUnionWarSimpleList);
            for (CrossUnionWarSimple unionWarSimple : crossUnionWarSimpleList) {
                boolean isInitOver = false;
                for (String unionUid : initUnionRankOverMap.get(activityId).get(phase)) {
                    if (Objects.equals(unionUid, unionWarSimple.getUnionUid())) {
                        isInitOver = true;
                        break;
                    }
                }
                if (isInitOver) {
                    continue;
                }
                UnionActivityRank unionRank = new UnionActivityRank(activityId, groupId);
                unionRank.setPhase(phase);
                unionRank.setUnionUid(unionWarSimple.getUnionUid());
                unionRank.setUnionBaseInfo(unionWarSimple.getUnionBaseInfo());
                unionRank.setValue(BigInteger.ZERO);
                unionRank.setLastUpdateTime(System.currentTimeMillis());
                unionRank.setGroupId(groupId);
                changeUnionWarRank(activityId, phase, unionRank, true, groupId);
                initUnionRankOverMap.get(activityId).get(phase).add(unionWarSimple.getUnionUid());
            }
        }
    }

    /**
     * 获取阶段对应的排行榜conditionType
     * @param phase 阶段
     * @return conditionType
     */
    private static int getConditionTypeByPhase(int phase) {
        for (eUnionWarRankConditionType value : eUnionWarRankConditionType.values()) {
            if (value.getPhase() == phase) {
                return value.getConditionType();
            }
        }
        return 0;
    }

    /**
     * 获取排行榜conditionType对应的阶段
     * @param conditionType 条件类型
     * @return  阶段
     */
    private static int getPhaseByConditionType(int conditionType) {
        for (eUnionWarRankConditionType value : eUnionWarRankConditionType.values()) {
            if (value.getConditionType() == conditionType) {
                return value.getPhase();
            }
        }
        return 0;
    }

    /**
     * 获取商会名次
     */
    public static int getUnionWarRank(int activityId, int conditionType, long serverId, String unionUid, long playerId) {
        int rank = -1;
        int groupId = Cross2UnionActivityGroupMgr.getGroupId(activityId, playerId);
        if(groupId == UnionActivityGroupHelper.NO_GROUP_ID){
            return rank;
        }
        CrossUnionWarRankListModel rankListModel = getCrossUnionWarRankListModel(activityId, getPhaseByConditionType(conditionType), groupId);
        if (null != rankListModel) {
            rank = rankListModel.getMyRank(serverId, unionUid);
        }
        int maxRank = getMaxRank(activityId, conditionType);
        if (rank > maxRank) {
            rank = -1;
        }
        return rank;
    }

    /**
     * 获取活动配置的最大名次
     */
    private static int getMaxRank(int activityId, int conditionType){
        int maxRank = GameConfig.RANK_DEFAULT_MAX_COUNT;
        ActivityInfo activityInfo = CrossUnionWarActivityMgr.getOpenActivity(activityId);
        if(null != activityInfo) {
            maxRank = ActivityHelper.getMaxRankByConditionType(conditionType, CrossUnionWarActivityMgr.getActivityConditionInfoList(activityInfo.getActivityId()));
        }
        return maxRank;
    }

    /**
     * 新增冠军商会
     * @param activityInfo  活动信息
     */
    public static boolean addChampion(ActivityInfo activityInfo) {
        synchronized (unionWarChampionMap) {
            int timeMark = getTimeMark();
            if (!unionWarChampionMap.containsKey(timeMark)) {
                unionWarChampionMap.put(timeMark, new ConcurrentHashMap<>());
            }
            if (!unionWarChampionMap.get(timeMark).containsKey(activityInfo.getActivityId())) {
                unionWarChampionMap.get(timeMark).put(activityInfo.getActivityId(), new ArrayList<>());
            }
            List<Integer> groupIdList = CrossUnionWarMgr.getGroupListByCrossServerId(activityInfo.getActivityId(), CrossBaseServer.getInstance().getServerId());
            for (int groupId : groupIdList) {
                UnionActivityGroup group = Cross2UnionActivityGroupMgr.getGroupData(activityInfo.getActivityId(), groupId);
                if(group == null){
                    continue;
                }
                CrossUnionWarSimple simple = CrossUnionWarMgr.getChampion(activityInfo.getActivityId(), groupId);
                boolean exist = false;
                for (UnionWarChampionUnionInfo unionInfo : unionWarChampionMap.get(timeMark).get(activityInfo.getActivityId())) {
                    if(unionInfo.getGroupId() == groupId){
                        exist = true;
                        break;
                    }
                }
                if(simple != null && !exist) {
                    getLogger().info("addChampion unionUid {}", simple.getUnionUid());
                    UnionWarChampionUnionInfo championUnionInfo = new UnionWarChampionUnionInfo();
                    championUnionInfo.setTimeMark(timeMark);
                    championUnionInfo.setServerIdList(StringUtils.listToString(new ArrayList(group.getServerSet()), ","));
                    championUnionInfo.setUnionBaseInfo(simple.getUnionBaseInfo());
                    championUnionInfo.setUnionUid(simple.getUnionUid());
                    championUnionInfo.setActivityId(activityInfo.getActivityId());
                    championUnionInfo.setInsertOption();
                    championUnionInfo.setGroupId(groupId);
                    unionWarChampionMap.get(timeMark).get(activityInfo.getActivityId()).add(championUnionInfo);
                    getLogger().info("addChampion success {} {} {} {}", timeMark, activityInfo.getActivityId(), groupId, simple.getUnionUid());
                }
            }
            sendChampionDataToGameServer();
        }
        return true;
    }

    /**
     * 同步冠军数据给游戏服
     */
    public static void sendChampionDataToGameServer() {
        Map<Long, List<CrossUnionWarProto.UnionWarChampionTemp.Builder>> syncMap = new ConcurrentHashMap<>();
        for (Map<Integer, List<UnionWarChampionUnionInfo>> map : unionWarChampionMap.values()) {
            for (List<UnionWarChampionUnionInfo> championList : map.values()) {
                for (int i = 0; i < championList.size(); i++) {
                    UnionWarChampionUnionInfo champion  = championList.get(i);
                    //todo
                    //group activityId
                    Set<Long> sendServerIdSet = new HashSet<>();
                    for (String idStr : champion.getServerIdList().split(",")) {
                        sendServerIdSet.add(Long.valueOf(idStr));
                    }
                    for (Long serverId : sendServerIdSet) {
                        if (!syncMap.containsKey(serverId)) {
                            syncMap.put(serverId, new ArrayList<>());
                        }
                        syncMap.get(serverId).add(parseChampionTemp(champion));
                    }
                }
            }
        }

        for (Map.Entry<Long, List<CrossUnionWarProto.UnionWarChampionTemp.Builder>> entry : syncMap.entrySet()) {
            CrossUnionWarProto.UnionWarChampionSyncListMsg.Builder builder = CrossUnionWarProto.UnionWarChampionSyncListMsg.newBuilder();
            for (CrossUnionWarProto.UnionWarChampionTemp.Builder champion : entry.getValue()) {
                builder.addChampion(champion);
            }
            getLogger().info("sync champion to serverId {}", entry.getKey());
            MessageHelper.sendPacket(entry.getKey(), 0,
                    YanQuMessageUtils.buildMessage(GameProtocol.S_UNION_WAR_ACTIVITY_RECEIVE_CHAMPION_DATA, builder));
        }
    }

    public static CrossUnionWarProto.UnionWarChampionTemp.Builder parseChampionTemp(UnionWarChampionUnionInfo champion) {
        CrossUnionWarProto.UnionWarChampionTemp.Builder championTemp = CrossUnionWarProto.UnionWarChampionTemp.newBuilder();
        championTemp.setTimeMark(champion.getTimeMark());
        championTemp.setActivityId(champion.getActivityId());
        championTemp.setUnionUid(champion.getUnionUid());
        championTemp.addAllServerId(StringUtils.stringToLongList(champion.getServerIdList(), ","));
        championTemp.setUnionBaseTemp(UnionBasePb.parseUnionBaseTempMsg(champion.getUnionBaseInfo()));
        championTemp.setGroupId(champion.getGroupId());
        return championTemp;
    }

    /**
     * 单个游戏服请求新增冠军商会
     * @param serverId
     * @param activityId
     */
    public static void addChampionSingleServer(long serverId, int activityId) {
        if (unionWarChampionMap.containsKey(getTimeMark())) {
            if (unionWarChampionMap.get(getTimeMark()).containsKey(activityId)) {
                List<Integer> list = CrossUnionWarMgr.getGroupListByServerId(activityId, serverId);
                List<UnionWarChampionUnionInfo> championList = unionWarChampionMap.get(getTimeMark()).get(activityId);

                //过滤分组
                for (int groupId : list) {
                    for (UnionWarChampionUnionInfo champion : championList) {
                        if(champion.getGroupId() == groupId){
                            List<Long> serverList = StringUtils.stringToLongList(champion.getServerIdList(), ",");
                            CrossUnionWarProto.UnionWarChampionSyncListMsg.Builder builder = CrossUnionWarProto.UnionWarChampionSyncListMsg.newBuilder();
                            builder.addChampion(parseChampionTemp(champion));
                            if (serverList.contains(serverId)) {
                                MessageHelper.sendPacket(serverId, 0,
                                        YanQuMessageUtils.buildMessage(GameProtocol.S_UNION_WAR_ACTIVITY_RECEIVE_CHAMPION_DATA, builder));
                            }
                        }
                    }
                }
                for (int i = championList.size() - 1; i >= 0; i--) {
                    UnionWarChampionUnionInfo champion = championList.get(i);

                }

            }
        }
    }

    private static int getTimeMark() {
        Calendar cal = Calendar.getInstance();
        int year = cal.get(Calendar.YEAR);
        int month = cal.get(Calendar.MONTH) + 1;
        String monthStr = month < 10 ? "0" + month : month + "";
        String timeStr = year + monthStr;
        return Integer.valueOf(timeStr);
    }

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean stop() {
        return false;
    }

    public boolean save() {
        for (Map.Entry<Integer, Map<Integer, Map<Integer, CrossUnionWarRankListModel>>> activityEntry : unionWarRankListModelMap.entrySet()) {
            for (Map.Entry<Integer, Map<Integer, CrossUnionWarRankListModel>> phaseEntry : activityEntry.getValue().entrySet()) {
                for (Map.Entry<Integer, CrossUnionWarRankListModel> groupEntry : phaseEntry.getValue().entrySet()) {
                    CrossUnionWarRankListModel  rankListModel = groupEntry.getValue();
                    if (rankListModel.isUpdate()) {
                        rankListModel.saveUnionWarRankList();
                    }
                }
            }
        }

        for (Map<Integer, List<UnionWarChampionUnionInfo>> map : unionWarChampionMap.values()) {
            for (List<UnionWarChampionUnionInfo> championList : map.values()) {
                for (int i = 0; i < championList.size(); i++) {
                    UnionWarChampionUnionInfo champion = championList.get(i);
                    if (champion.isInsertOption()) {
                        UnionWarActivityBusiness.addUnionWarChampionMap(champion);
                    }
                }

            }
        }
        return true;
    }
}
